<?php
namespace Helpers;

use Admin\Models\device\XhsysDeviceSignIn;
use Admin\Models\device\XhsysUsertablet;
use Admin\Models\device\XhsysAccountdevicelocked;
use Admin\Models\device\XhsysDevicerepair;
use Admin\Models\user\XhsysUser;

class Device
{

    private static $enum = [
        'iReceivePurpose'   => [0 => '自用', 1 => '备用', 2 => '学校公用', 3 => '教师机']
    ];
    /**
     * 判断用户是否可借用该机器
     *
     * @param $userId
     * @param $devNumber
     * @return bool
     * @throws \Exception
     *
     * create by ck 20171220
     */
    public static function allowBorrow($userId, $devNumber)
    {
        //检查是否有备用机
        if (self::hasSpare($userId)) {
            throw new \Exception('该用户已有备用机，不可借用');
        }
        //检查是否有借用机
        if (self::hasBorrow($userId)) {
            throw new \Exception('该用户已借用机器，不可继续借用');
        }
        //检查是否为备用机
        if (self::isSpare($devNumber)) {
            throw new \Exception('不可借用备用机');
        }
        //检查是否为正常绑定设备
        $checkDev = XhsysAccountdevicelocked::find([
            'columns'    => 'iUserId,iSourceType',
            'conditions' => 'bDelete = 0 AND sDeviceNumber = :devNumber:',
            'bind'       => ['devNumber' => $devNumber]
        ]);
        if (count($checkDev) != 1) {
            throw new \Exception('该设备不可借用');
        }
        if ($checkDev[0]->iUserId == $userId) {
            throw new \Exception('不可借用自己设备');
        }
        if ($checkDev[0]->iSourceType != 1) {
            throw new \Exception('该设备非正常绑定设备，不可借用');
        }
        return true;
    }

    public static function allowUseSpare($userId, $devNumber)
    {

    }

    /**
     * 是否有借用机
     *
     * @param $userId
     * @return bool
     *
     * create by ck 20171220
     */
    public static function hasBorrow($userId)
    {
        return !!XhsysAccountdevicelocked::count([
            'conditions' => 'bDelete = 0 AND iUserId = :userId: AND iSourceType = 2',
            'bind'       => ['userId' => $userId]
        ]);
    }

    /**
     * 是否使用备用机
     *
     * @param $userId
     * @return bool
     *
     * create by ck 20171220
     */
    public static function hasSpare($userId)
    {
        return !!XhsysUsertablet::count([
            'conditions' => 'bDelete = 0 AND bDone = 0 AND sNowReceiverAccount = :account:',
            'bind'       => ['account' => User::getLogonName($userId)]
        ]);
    }

    /**
     * 更改用户绑定设备（删除后新增）
     *
     * @param $userId
     * @param $devNumber
     *
     * create by
     */
    public static function changeDevNumber($userId, $devNumber)
    {

    }

    /**
     * 获取绑定平板信息
     *
     * @param null $userId
     * @return array|bool
     *
     * create by ck 20180530
     */
    public static function getBindTablet($userId = null)
    {
        $userId or $userId = User::getId();
        $bindDev = XhsysAccountdevicelocked::findFirst([
            'conditions' => 'bDelete = 0 AND iSourceType = 1 AND iUserId = :userId:',
            'bind'       => ['userId' => $userId]
        ]);
//        if (!$bindDev) {
//            return false;
//        }
//        $bindDev = $bindDev->toArray();
//        return [
//            'id'        => $bindDev['iADLId'],
//            'devNumber' => $bindDev['sDeviceNumber'],
//            'mac'       => $bindDev['sMac'],
//            'model'     => $bindDev['sModel'],
//            'imei'      => $bindDev['sImei']
//        ];
        return $bindDev ? $bindDev->toArray() : false;
    }

    public static function tabletBindNum($devNumber)
    {
        return XhsysAccountdevicelocked::count([
            'conditions' => 'bDelete = 0 AND sDeviceNumber = :devNumber:',
            'bind'       => ['devNumber' => $devNumber]
        ]);
    }

    /**
     * 判断是否为备用机
     *
     * @param $devNumber
     * @return bool
     *
     * create by ck 20171220
     */
    private static function isSpare($devNumber)
    {
        return !!XhsysUsertablet::count([
            'conditions' => 'bDelete = 0 AND sDevNumber = :devNumber: AND (bDone = 0 OR iReceiveStatus <> 3)',
            'bind'       => ['devNumber' => $devNumber]
        ]);
    }

    /**
     * 判断是否为借用机
     *
     * @param $devNumber
     * @return bool
     *
     * create by ck 20171220
     */
    private static function isBorrow($devNumber)
    {
        return !!XhsysAccountdevicelocked::count([
            'conditions' => 'bDelete = 0 AND sDeviceNumber = :devNumber: AND iSourceType = 2',
            'bind'       => ['devNumber' => $devNumber]
        ]);
    }

    /**
     * 绑定教师机
     *
     * @param $code
     * @param $tchId
     * @param $schoolId
     * @return bool
     * @throws XhException
     *
     * create by xjq 20180625
     * modify by dale 20180713   弃用
     */
    public static function bindTchTablet($code , $tchId ,$schoolId){
        if(!$code || !$tchId){
            throw new XhException('缺少参数');
        }
        $checkTab = XhsysUsertablet::findFirst([
            'conditions' => 'sDevNumber = :sDevNumber: ',
            'bind'       => ['sDevNumber' => $code]
        ]);

        if($checkTab && !$checkTab->bDelete && $checkTab->iReceiveStatus  &&  $checkTab->iReceiveStatus != 3){
            throw new XhException('设备号为：'.$code.'的设备未归还无法申请');
        }
        $tablet = new XhsysUsertablet();
        $user = XhsysUser::findFirst($tchId);
        $tablet->sReceiverName    = $user->sUserName;
        $tablet->sReceiverPhone   = $user->sSelfPhone;
        $tablet->sReceiverAccount = $user->sLogonName;
        $tablet->iReceivePurpose  = 3; //教师机
        $tablet->iReceiveStatus   = 2;//领用
        $tablet->iSchoolId        = $schoolId;
        $tablet->sDevNumber       = $code;
        $tablet->tReceiveTime     = date('Y-m-d H:i:s',time());
        if(!$tablet->save()){
            throw new XhException('绑定教师机失败');
        }
        return true;
    }

    /**
     * 绑定设备
     *
     * @param $userId
     * @param $devNumber
     * @return bool
     * @throws \Exception
     *
     * create by ck 20180711
     * modify by ck 20181113
     */
    public static function bindTablet($userId, $devNumber)
    {
        //判断设备是否已被绑定
        $bindCount = XhsysAccountdevicelocked::count([
            'conditions' => 'sDeviceNumber = :devNumber: AND bDelete = 0',
            'bind'       => ['devNumber' => $devNumber]
        ]);
        if ($bindCount) {
            throw new \Exception('设备已被绑定');
        }

        //判断用户是否已绑定设备
        $bindCount = XhsysAccountdevicelocked::count([
            'conditions' => 'iUserId = :userId: AND bDelete = 0',
            'bind'       => ['userId' => $userId]
        ]);
        if ($bindCount) {
            throw new \Exception('用户已有绑定设备');
        }

        //判断设备是否被领用
        $tablet = XhsysUsertablet::findFirst([
            'conditions' => 'sDevNumber = :devNumber:',
            'bind'       => ['devNumber' => $devNumber],
            'order'      => 'iUTId desc'
        ]);
        if ($tablet && !$tablet->bDelete) {
            throw new \Exception('该设备已被领用');
        }

        //绑定
        $dev = new XhsysAccountdevicelocked();
        $dev->iUserId       = $userId;
        $dev->sLogonName    = User::getLogonName($userId);
        $dev->sDeviceNumber = $devNumber;
        $dev->iImport       = 0;
        return $dev->save();
    }

    /**
     * 根据UserId获取设备数据
     *
     * @param string $userId
     * @param string $type 1自用2备用
     *
     * @return mixed
     * @throws XhException
     *
     * create by qgz 20181219
     */
    public static function getRegisterDataByUserId($userId = '', $type = '')
    {
        if (!$userId) {
            throw new XhException("没有人员参数");
        }
        if (!in_array((int)$type, [1, 2])) {
            throw new XhException("类型参数错误");
        }
        $type = (int)$type - 1;
        $userInfo = XhsysUser::findFirst([
            'columns' => 'iUserId, sUserName, sLogonName, sSelfPhone',
            'conditions' => 'bDelete = 0 and iUserId = :iUserId:',
            'bind' => ['iUserId' => $userId]
        ]);
        if (!$userInfo) {
            return [];
        }
        $userInfo = $userInfo->toArray();
        $data = XhsysUsertablet::find([
            'columns' => "iUTId, sReceiverName, sDevNumber, iReceivePurpose, sDevType, tReceiveTime, CASE iReceiveStatus WHEN 1 THEN '待领用' WHEN 2 THEN '已领用' WHEN 3 THEN '已归还' END AS iReceiveStatus, iSchoolId ",
            'conditions' => "bDelete = 0 and iReceivePurpose = {$type} and bHistory = 0 and sReceiverName = :sReceiverName: and sReceiverAccount = :sReceiverAccount: and sReceiverPhone = :sReceiverPhone:",
            'bind' => [
                'sReceiverName' => $userInfo['sUserName'],
                'sReceiverAccount' => $userInfo['sLogonName'],
                'sReceiverPhone' => $userInfo['sSelfPhone']
            ]
        ])->toArray();
        return $data;
    }

    /**
     * 根据用户id获取当前绑定设备
     *
     * @param $userId
     *
     * @return array
     * @throws XhException
     *
     * create by qgz 20190107
     */
    public static function getBoundByUserId($userId)
    {
        if (!$userId) {
            throw new XhException("缺少用户id参数");
        }
        //当前绑定数据
        $findDev = XhsysAccountdevicelocked::findFirst([
            'columns'    => 'sModel, sDeviceNumber, sMac, tCreateDate',
            'conditions' => 'bDelete = 0 AND iUserId = :iUserId:',
            'bind'       => ['iUserId' => $userId],
            'order' => 'tLastModifyDate DESC',
        ]);
        $return = $findDev ? $findDev->toArray() : [];

        //当前使用数据
        $nowUseDev = XhsysUsertablet::findFirst([
            'columns' => 'sDevNumber, tNowReceiveTime, iReceivePurpose',
            'conditions' => 'bDelete = 0 AND bDone = 0 AND iNowReceiverId = :iNowReceiverId: ',
            'bind' => ['iNowReceiverId' => $userId],
            'order' => 'tNowReceiveTime DESC'
        ]);
        if ($nowUseDev) {
            $nowUseDev = $nowUseDev->toArray();
            $enum = self::$enum['iReceivePurpose'];
            $nowUseDev['iReceivePurpose'] = isset($enum[$nowUseDev['iReceivePurpose']]) ? $enum[$nowUseDev['iReceivePurpose']] : '';
        }
        $return['nowUseInfo'] = $nowUseDev ? $nowUseDev : [];
        return $return;
    }

    /**
     * 根据用户id获取该用户有关的社会历史
     *
     * @param $userId
     *
     * @return array
     * @throws XhException
     *
     * create by qgz 20190107
     */
    public static function getDevHistoryByUserId($userId)
    {
        if (!$userId) {
            throw new XhException("缺少用户id参数");
        }
        $data = [];
        //学生机
        $boundDev = XhsysAccountdevicelocked::find([
            'columns'    => 'sDeviceNumber, tCreateDate, tLastModifyDate',
            'conditions' => 'iUserId = :iUserId:',
            'bind'       => ['iUserId' => $userId],
            'order' => 'tCreateDate DESC',
        ])->toArray();
        if ($boundDev) {
            foreach ($boundDev as $value) {
                $info = [
                    'type' => '学生机',
                    'devNumber' => $value['sDeviceNumber'],
                    'start' => $value['tCreateDate'],
                    'end' => $value['tLastModifyDate']
                ];
                if ($value['tLastModifyDate'] && $value['tCreateDate'] &&
                    ($value['tLastModifyDate'] > $value['tCreateDate'])) {
                    $info['long'] = ceil((strtotime($value['tLastModifyDate']) - strtotime($value['tCreateDate']))
                                         / 3600);
                } else {
                    $info['long'] = '';
                }
                $data[] = $info;
            }
            unset($value, $info);
        }
        //备用机自用机等
        $tabDev = XhsysUsertablet::find([
            'columns' => 'sDevNumber, tNowReceiveTime, tLastModifyDate, iReceivePurpose',
            'conditions' => 'bDelete = 0 AND bDone = 1 AND iNowReceiverId = :iNowReceiverId: ',
            'bind' => ['iNowReceiverId' => $userId]
        ])->toArray();
        if ($tabDev) {
            $enum = self::$enum['iReceivePurpose'];
            foreach ($tabDev as $value) {
                $info = [
                    'type' => isset($enum[$value['iReceivePurpose']]) ? $enum[$value['iReceivePurpose']] : '',
                    'devNumber' => $value['sDevNumber'],
                    'start' => $value['tNowReceiveTime'],
                    'end' => $value['tLastModifyDate']
                ];
                if ($value['tLastModifyDate'] && $value['tNowReceiveTime'] &&
                    ($value['tLastModifyDate'] > $value['tNowReceiveTime'])) {
                    $info['long'] = ceil((strtotime($value['tLastModifyDate']) - strtotime($value['tNowReceiveTime']))
                                    / 3600);
                } else {
                    $info['long'] = '';
                }
                $data[] = $info;
            }
            unset($value, $info);
        }
        if ($data) {//按开始时间排序
            array_multisort(array_column($data, 'start'), SORT_DESC, $data);
        }
        return $data;
    }

    /**
     * 根据用户id获取该用户设备维修数据
     *
     * @param $userId
     *
     * @return array
     * @throws XhException
     *
     * create by qgz 20190108
     */
    public static function getRepairDevByUserId($userId)
    {
        if (!$userId) {
            throw new XhException("缺少用户id参数");
        }
        $data = XhsysDevicerepair::find([
            'columns' => 'sRepairProjectName, sDeviceNumber, sNewDeviceNumber, sRepairDate as sStartDate,
            tLastModifyDate as sEndDate, iStatus',
            'conditions' => 'bDelete = 0 and iUserId = :iUserId:',
            'bind' => ['iUserId' => $userId],
            'order' => 'sRepairDate DESC, tLastModifyDate DESC',
        ])->toArray();
        if ($data) {
            foreach ($data as &$value) {
                if (!in_array($value['iStatus'], [10, 11, 12])) {//正常开机、返回重修、无法维修状态没有结束时间
                    $value['sEndDate'] = '';
                }
            }
        }
        return $data;
    }

    /**
     * 设置状态开关
     *
     * @param array $paramsArr 用户['userId' => 123, 'deviceNumber' => 'abc']数组
     * @param string $type 1签收2协议3配件
     * @param string $status 0关1开
     *
     * @return bool
     * @throws XhException
     *
     * create by qgz 20190123
     */
    public static function addSignInData($paramsArr = [], $type = '', $status = '')
    {
        $dataArr = array_column($paramsArr, 'deviceNumber', 'userId');
        $userIdArr = array_values(array_filter(array_unique(array_values(array_column($paramsArr, 'userId')))));
        if (!$userIdArr) {
            throw new XhException("用户id参数不能为空");
        }
        if (!in_array($type, [1, 2, 3])) {
            throw new XhException("类型参数不正确");
        }
        if (!in_array($status, [0, 1])) {
            throw new XhException("状态参数不正确");
        }
        Di::get()->db->begin();
        $userData = XhsysUser::find([
            'columns' => 'iUserId, sLogonName, iSchoolId, sAdClsName',
            'conditions' => "bDelete = 0 and iUserId in ({iUserIdArr:array})",
            'bind' => ['iUserIdArr' => $userIdArr]
        ])->toArray();
        if (!$userData) {
            throw new XhException("找不到人员数据");
        }
        $userData = array_column($userData, null, 'iUserId');

        $existData = XhsysDeviceSignIn::find([
            'conditions' => "bDelete = 0 and iStatus != 2 and iUserId in ({iUserIdArr:array})",
            'bind' => ['iUserIdArr' => $userIdArr]
        ]);
        if (!$existData) {//都需要新增
            foreach ($userIdArr as $userId) {
                //设备号为空的过滤掉不操作
                if (isset($dataArr[$userId]) && $dataArr[$userId]) {
                    $pro = new XhsysDeviceSignIn();
                    $pro->iUserId = $userId;
                    $pro->sLogonName = isset($userData[$userId]) ? $userData[$userId]['sLogonName'] : '';
                    $pro->iSchoolId = isset($userData[$userId]) ? $userData[$userId]['iSchoolId'] : '';
                    $pro->sAdClsName = isset($userData[$userId]) ? $userData[$userId]['sAdClsName'] : '';
                    $pro->sDeviceNumber = $dataArr[$userId];
                    $pro->iSignInStatus = $type == 1 ? $status : 0;
                    $pro->iProtocolStatus = $type == 2 ? $status : 0;
                    $pro->iPartsStatus = $type == 3 ? $status : 0;
                    if (!$pro->save()) {
                        Di::get()->db->rollback();
                        throw new XhException("保存数据出错，id：" . $userId);
                    }
                }
            }
            Di::get()->db->commit();
            return true;
        }
        $findUserIdArr = [];
        foreach ($existData as $datum) {
            //设备号为空的过滤掉不操作
            if ($dataArr[$datum->iUserId] && $dataArr[$datum->iUserId] == $datum->sDeviceNumber) {
                switch ($type) {
                    case 1:
                        $datum->iSignInStatus = $status;
                        break;
                    case 2:
                        $datum->iProtocolStatus = $status;
                        break;
                    case 3:
                        $datum->iPartsStatus = $status;
                        break;
                    default:
                        break;
                }
                if (!$datum->save()) {
                    Di::get()->db->rollback();
                    throw new XhException("更新数据出错，id：" . $datum->iUserId);
                }
                $findUserIdArr[] = $datum->iUserId;
            }
        }
        $outArr = array_diff($userIdArr, $findUserIdArr);
        if ($outArr) {
            foreach ($outArr as $userId) {
                //设备号为空的过滤掉不操作
                if (isset($dataArr[$userId]) && $dataArr[$userId]) {
                    $pro = new XhsysDeviceSignIn();
                    $pro->iUserId = $userId;
                    $pro->sLogonName = isset($userData[$userId]) ? $userData[$userId]['sLogonName'] : '';
                    $pro->iSchoolId = isset($userData[$userId]) ? $userData[$userId]['iSchoolId'] : '';
                    $pro->sAdClsName = isset($userData[$userId]) ? $userData[$userId]['sAdClsName'] : '';
                    $pro->sDeviceNumber = $dataArr[$userId];
                    $pro->iSignInStatus = $type == 1 ? $status : 0;
                    $pro->iProtocolStatus = $type == 2 ? $status : 0;
                    $pro->iPartsStatus = $type == 3 ? $status : 0;
                    if (!$pro->save()) {
                        Di::get()->db->rollback();
                        throw new XhException("添加数据出错，id：" . $userId);
                    }
                }
            }
        }
        Di::get()->db->commit();
        return true;
    }

    /**
     * 获取签收状态数据
     *
     * @param array $paramsArr 用户['userId' => 123, 'deviceNumber' => 'abc']数组
     *
     * @return array
     * @throws XhException
     *
     * create by qgz 20190129
     */
    public static function getSignInData($paramsArr = [])
    {
        $dataArr = array_column($paramsArr, 'deviceNumber', 'userId');
        if (!$paramsArr) {
            throw new XhException("缺少参数");
        }
        $userIdArr = array_values(array_filter(array_unique(array_values(array_column($paramsArr, 'userId')))));
        if (!$userIdArr) {
            throw new XhException("用户id参数错误");
        }

        $return = [];
        $findData = XhsysDeviceSignIn::find([
            'columns' => 'sDeviceNumber, iUserId as userId, iSignInStatus as signInStatus, iProtocolStatus as protocolStatus, iPartsStatus as partsStatus, sSignatureUrl as signatureUrl, iStatus',
            'conditions' => "bDelete = 0 and iStatus != 2 and iUserId in ({userId:array})",
            'bind' => ['userId' => $userIdArr]
        ])->toArray();
        if (!$findData) {
            //签收表中找不到，去绑定表查询
            foreach ($userIdArr as $userId) {
                $status = [
                    'sDeviceNumber' => $dataArr[$userId],
                    'userId' => $userId,
                    'signInStatus' => 0,
                    'protocolStatus' => 0,
                    'partsStatus' => 0,
                    'signatureUrl' => 0,
                    'iStatus' => 0
                ];
                $findData = XhsysAccountdevicelocked::findFirst([
                    'conditions' => 'iUserId = :iUserId: and sDeviceNumber = :sDeviceNumber: and bDelete = 0',
                    'bind' => ['iUserId' => $userId, 'sDeviceNumber' => $dataArr[$userId]]
                ]);
                if ($findData) {
                    $status['iStatus'] = 1;//找到绑定状态为已签收，其他默认为0关
                }
                $return[$userId] = $status;
            }
            return array_column(array_values($return), null, 'userId');;
        }
        $existArr = [];
        foreach ($paramsArr as $value) {
            foreach ($findData as $item) {
                //已经存在状态
                if ($value['userId'] == $item['userId'] && $value['deviceNumber'] == $item['sDeviceNumber']) {
                    if (!isset($existArr[$item['userId']])) {
                        $existArr[$value['userId']] = $item;
                    }
                }
            }
        }
        //不存在状态返回默认值
        $outArr = array_diff($userIdArr, array_values(array_keys($existArr)));
        if ($outArr) {
            foreach ($outArr as $userId) {
                $status = [
                    'sDeviceNumber' => $dataArr[$userId],
                    'userId' => $userId,
                    'signInStatus' => 0,
                    'protocolStatus' => 0,
                    'partsStatus' => 0,
                    'signatureUrl' => 0,
                    'iStatus' => 0
                ];
                //签收表中找不到，去绑定表查询
                $findData = XhsysAccountdevicelocked::findFirst([
                    'conditions' => 'iUserId = :iUserId: and sDeviceNumber = :sDeviceNumber: and bDelete = 0',
                    'bind' => ['iUserId' => $userId, 'sDeviceNumber' => $dataArr[$userId]]
                ]);
                if ($findData) {
                    $status['iStatus'] = 1;//找到绑定状态为已签收，其他默认为0关
                }
                $existArr[$userId] = $status;
            }
        }
        return array_column(array_values($existArr), null, 'userId');
    }
}
